ChatGPTの履歴データがExportできるようになっていました
はじめに
データアナリティクス事業本部ビッグデータチームのkasamaです。
OpenAI社の公式の記事やTwitterからもChatGPTの履歴データがExportできるようになっていたので、その内容を調べてみたいと思います。
※ 本ブログは2023/04/16現在の機能を試してみたブログになります。今後、新機能の追加や修正が見込めれますのであらかじめご了承ください。
How do I export my ChatGPT history?
前提条件
- OpenAI社の公式記事より、フリープラン、plusプランどちらでも使用できる機能であることがわかりますが、私はPlusプランに入っているのでそちらで検証していきます。
- Modelとしての差も検証するため、
GPT-3.5
とGPT-4
に同一の質問を行い、履歴データを見てみます。 - 質問内容は「Pythonプログラミングを学習する手順を200文字以内で教えてください。」とします。
- フィードバックについては、どちらも
good
ボタンと「とても参考になりました。ありがとうございます。」とします。
GPT-3.5
GPT-4
フィードバック
Exportしてみる
画面左側の'Settings'ボタンよりExport data
できますので、そちらからExportします。
Export Dataを押下するとすぐに登録済みのメールアドレスに以下のメールが届きます。ダウンロードリンクの有効期限が24時間以内なので、注意をする必要があります。
履歴データの確認
メールのリンクよりzipファイルがダウンロードされます。展開すると以下のファイルが格納されていましたので、それぞれ確認します。
chat.html
chat.html
は、ユーザーとChatGPTとの会話履歴をHTML形式できます。発言者を識別するためにuser
とassistant
で識別されています。ブラウザ上で簡単に確認したい際に便利です。
conversations.json
conversations.json
は、ChatGPTを使用して生成された会話データを格納するjsonファイルです。
詳細な構造に関しては調査が必要ですが、ざっとみたところ、アクション毎に構造化されてidが割り振られており、roleでuser
やassistant
の識別、parts
で会話内容を取得できるようです。modelについてもmodel_slug
の値より、使用しているmodelを確認できます。会話内容の日本語は、JSONファイルに出力する際、「\u30e6」のようなUnicodeエスケープ(シーケンス)という形式で出力しますので、文字列をデコードする必要があります。
conversations.json
[ { "title": "Python\u5b66\u7fd2\u624b\u9806", "create_time": 1681601164.65984, "update_time": 1681601191.0, "mapping": { "c26cc27c-e5bd-4317-97f2-862ab97922e4": { "id": "c26cc27c-e5bd-4317-97f2-862ab97922e4", "message": { "id": "c26cc27c-e5bd-4317-97f2-862ab97922e4", "author": { "role": "system", "name": null, "metadata": {} }, "create_time": 1681601164.65984, "update_time": null, "content": { "content_type": "text", "parts": [ "" ] }, "end_turn": true, "weight": 1.0, "metadata": {}, "recipient": "all" }, "parent": "037e2793-7290-4074-913f-f7db3f501beb", "children": [ "a0a6d4f1-5f11-43ef-ae51-3d12a0b69657" ] }, "037e2793-7290-4074-913f-f7db3f501beb": { "id": "037e2793-7290-4074-913f-f7db3f501beb", "message": null, "parent": null, "children": [ "c26cc27c-e5bd-4317-97f2-862ab97922e4" ] }, "a0a6d4f1-5f11-43ef-ae51-3d12a0b69657": { "id": "a0a6d4f1-5f11-43ef-ae51-3d12a0b69657", "message": { "id": "a0a6d4f1-5f11-43ef-ae51-3d12a0b69657", "author": { "role": "user", "name": null, "metadata": {} }, "create_time": 1681601164.6619, "update_time": null, "content": { "content_type": "text", "parts": [ "Python\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u3092\u5b66\u7fd2\u3059\u308b\u624b\u9806\u3092200\u6587\u5b57\u4ee5\u5185\u3067\u6559\u3048\u3066\u304f\u3060\u3055\u3044\u3002" ] }, "end_turn": null, "weight": 1.0, "metadata": { "timestamp_": "absolute", "message_type": null }, "recipient": "all" }, "parent": "c26cc27c-e5bd-4317-97f2-862ab97922e4", "children": [ "8be7ff68-cb33-4c35-99c4-a7cd91709886" ] }, "8be7ff68-cb33-4c35-99c4-a7cd91709886": { "id": "8be7ff68-cb33-4c35-99c4-a7cd91709886", "message": { "id": "8be7ff68-cb33-4c35-99c4-a7cd91709886", "author": { "role": "assistant", "name": null, "metadata": {} }, "create_time": 1681601190.963448, "update_time": null, "content": { "content_type": "text", "parts": [ "1. Python\u57fa\u790e\u3092\u5b66\u3076: \u516c\u5f0f\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3084\u30aa\u30f3\u30e9\u30a4\u30f3\u30c1\u30e5\u30fc\u30c8\u30ea\u30a2\u30eb\u3092\u5229\u7528\n2. \u5b9f\u8df5\u7684\u306a\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306b\u53d6\u308a\u7d44\u3080: \u5c0f\u3055\u306a\u30bf\u30b9\u30af\u3092\u89e3\u6c7a\u3059\u308b\u30b3\u30fc\u30c9\u3092\u66f8\u304f\n3. \u30a8\u30e9\u30fc\u306b\u5bfe\u51e6: \u30b9\u30bf\u30c3\u30af\u30aa\u30fc\u30d0\u30fc\u30d5\u30ed\u30fc\u7b49\u3067\u60c5\u5831\u53ce\u96c6\u3057\u3001\u30c7\u30d0\u30c3\u30b0\u30b9\u30ad\u30eb\u3092\u8eab\u306b\u3064\u3051\u308b\n4. \u30b3\u30fc\u30c9\u54c1\u8cea\u5411\u4e0a: PEP 8\u306e\u30eb\u30fc\u30eb\u306b\u5f93\u3044\u3001\u30ea\u30fc\u30c0\u30d6\u30eb\u3067\u30e1\u30f3\u30c6\u30ca\u30d6\u30eb\u306a\u30b3\u30fc\u30c9\u3092\u66f8\u304f\n5. Python\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u4f7f\u3046: Numpy\u3001Pandas\u3001Matplotlib\u7b49\u306e\u4e00\u822c\u7684\u306a\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u7fd2\u5f97\n6. \u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u30b3\u30df\u30e5\u30cb\u30c6\u30a3\u306b\u53c2\u52a0: \u77e5\u8b58\u5171\u6709\u3084\u30d5\u30a3\u30fc\u30c9\u30d0\u30c3\u30af\u3092\u5f97\u308b\u305f\u3081\u306b\u6d3b\u52d5" ] }, "end_turn": true, "weight": 1.0, "metadata": { "message_type": null, "model_slug": "gpt-4", "finish_details": { "type": "stop", "stop": "<|diff_marker|>" }, "timestamp_": "absolute" }, "recipient": "all" }, "parent": "a0a6d4f1-5f11-43ef-ae51-3d12a0b69657", "children": [] } }, "moderation_results": [], "current_node": "8be7ff68-cb33-4c35-99c4-a7cd91709886", "plugin_ids": null, "id": "<id>" }, { "title": "Python Learning Steps.", "create_time": 1681601151.659016, "update_time": 1681601157.0, "mapping": { "8f6da518-2767-426c-bd56-a8e7cae1c8b3": { "id": "8f6da518-2767-426c-bd56-a8e7cae1c8b3", "message": { "id": "8f6da518-2767-426c-bd56-a8e7cae1c8b3", "author": { "role": "system", "name": null, "metadata": {} }, "create_time": 1681601151.659016, "update_time": null, "content": { "content_type": "text", "parts": [ "" ] }, "end_turn": true, "weight": 1.0, "metadata": {}, "recipient": "all" }, "parent": "d47bb8b9-e66b-4920-bee8-49859e4cf803", "children": [ "335bf015-2d56-4dbf-9148-eb6be0834b18" ] }, "d47bb8b9-e66b-4920-bee8-49859e4cf803": { "id": "d47bb8b9-e66b-4920-bee8-49859e4cf803", "message": null, "parent": null, "children": [ "8f6da518-2767-426c-bd56-a8e7cae1c8b3" ] }, "335bf015-2d56-4dbf-9148-eb6be0834b18": { "id": "335bf015-2d56-4dbf-9148-eb6be0834b18", "message": { "id": "335bf015-2d56-4dbf-9148-eb6be0834b18", "author": { "role": "user", "name": null, "metadata": {} }, "create_time": 1681601151.660363, "update_time": null, "content": { "content_type": "text", "parts": [ "Python\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u3092\u5b66\u7fd2\u3059\u308b\u624b\u9806\u3092200\u6587\u5b57\u4ee5\u5185\u3067\u6559\u3048\u3066\u304f\u3060\u3055\u3044\u3002" ] }, "end_turn": null, "weight": 1.0, "metadata": { "timestamp_": "absolute", "message_type": null }, "recipient": "all" }, "parent": "8f6da518-2767-426c-bd56-a8e7cae1c8b3", "children": [ "527c93ba-febe-4bd3-9783-f17f8835da14" ] }, "527c93ba-febe-4bd3-9783-f17f8835da14": { "id": "527c93ba-febe-4bd3-9783-f17f8835da14", "message": { "id": "527c93ba-febe-4bd3-9783-f17f8835da14", "author": { "role": "assistant", "name": null, "metadata": {} }, "create_time": 1681601156.501679, "update_time": null, "content": { "content_type": "text", "parts": [ "Python\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u3092\u5b66\u7fd2\u3059\u308b\u624b\u9806\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\u3002\n\n1. Python\u306e\u57fa\u672c\u6982\u5ff5\u3092\u5b66\u3076\uff1a\u30c7\u30fc\u30bf\u578b\u3001\u6f14\u7b97\u5b50\u3001\u5236\u5fa1\u69cb\u9020\u3001\u95a2\u6570\u306a\u3069\u306e\u57fa\u672c\u7684\u306a\u8981\u7d20\u3092\u5b66\u3073\u307e\u3059\u3002\n\n2. Python\u306e\u7d71\u5408\u958b\u767a\u74b0\u5883\uff08IDE\uff09\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3059\u308b\uff1a\u4f8b\u3048\u3070\u3001Anaconda\u3001PyCharm\u306a\u3069\u306eIDE\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u3001\u4f7f\u3044\u65b9\u3092\u899a\u3048\u307e\u3059\u3002\n\n3. \u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u306e\u5b9f\u8df5\uff1a\u5b66\u7fd2\u3057\u305f\u3053\u3068\u3092\u6d3b\u304b\u3057\u3001\u5c0f\u3055\u306a\u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u66f8\u3044\u3066\u5b9f\u8df5\u3057\u307e\u3059\u3002\u4f8b\u3048\u3070\u3001\u7c21\u5358\u306a\u8a08\u7b97\u6a5f\u3084\u6587\u5b57\u5217\u51e6\u7406\u306a\u3069\u3092\u66f8\u3044\u3066\u307f\u307e\u3059\u3002\n\n4. \u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u5b66\u3076\uff1aPython\u306e\u5f37\u529b\u306a\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u52b9\u7387\u7684\u306a\u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u4f5c\u6210\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u4f8b\u3048\u3070\u3001NumPy\u3001Pandas\u3001Matplotlib\u306a\u3069\u306e\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u5b66\u3073\u307e\u3059\u3002\n\n5. \u5b9f\u8df5\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3092\u884c\u3046\uff1a\u5b66\u7fd2\u3057\u305f\u3053\u3068\u3092\u6d3b\u304b\u3057\u3001\u5b9f\u8df5\u7684\u306a\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3092\u884c\u3044\u3001\u554f\u984c\u3092\u89e3\u6c7a\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3059\u3002\u4f8b\u3048\u3070\u3001Web\u30b9\u30af\u30ec\u30a4\u30d4\u30f3\u30b0\u3001\u30c7\u30fc\u30bf\u5206\u6790\u3001\u6a5f\u68b0\u5b66\u7fd2\u306a\u3069\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3092\u884c\u3044\u307e\u3059\u3002\n\n6. \u30b3\u30df\u30e5\u30cb\u30c6\u30a3\u306b\u53c2\u52a0\u3059\u308b\uff1aPython\u306e\u5b66\u7fd2\u8005\u30b3\u30df\u30e5\u30cb\u30c6\u30a3\u306b\u53c2\u52a0\u3059\u308b\u3053\u3068\u3067\u3001\u4ed6\u306e\u4eba\u3068\u60c5\u5831\u3092\u5171\u6709\u3057\u3001\u76f8\u4e92\u306b\u5b66\u3073\u5408\u3046\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u4f8b\u3048\u3070\u3001Stack Overflow\u3001GitHub\u3001Python\u30e6\u30fc\u30b6\u30fc\u4f1a\u306a\u3069\u306b\u53c2\u52a0\u3057\u307e\u3059\u3002" ] }, "end_turn": true, "weight": 1.0, "metadata": { "message_type": null, "model_slug": "text-davinci-002-render-sha", "finish_details": { "type": "stop", "stop": "<|im_end|>" }, "timestamp_": "absolute" }, "recipient": "all" }, "parent": "335bf015-2d56-4dbf-9148-eb6be0834b18", "children": [] } }, "moderation_results": [], "current_node": "527c93ba-febe-4bd3-9783-f17f8835da14", "plugin_ids": null, "id": "<id>" } ]
以下はテスト的にjsonファイルからデータを抽出したpython scriptです。
## conversations_decode.py import json with open("conversations.json", "r") as f: data = json.load(f) for item in data: title = item["title"] create_time = item["create_time"] update_time = item["update_time"] current_node = item["current_node"] print(f"Title: {title}") print(f"Create time: {create_time}") print(f"Update time: {update_time}") print(f"Current node: {current_node}") mapping = item["mapping"] for key in mapping.keys(): message = mapping[key]["message"] if message: message_id = message["id"] author_role = message["author"]["role"] content_parts = message["content"]["parts"] if "model_slug" in message["metadata"]: print("Model_slug:", message["metadata"]["model_slug"]) print(f"Message ID: {message_id}") print(f"Author role: {author_role}") print(f"Content parts: {content_parts}") print("\n")
実行結果
(base) kasama.yoshikitmp % python conversations_decode.py Title: Python学習手順 Create time: 1681601164.65984 Update time: 1681601191.0 Current node: 8be7ff68-cb33-4c35-99c4-a7cd91709886 Message ID: c26cc27c-e5bd-4317-97f2-862ab97922e4 Author role: system Content parts: [''] Message ID: a0a6d4f1-5f11-43ef-ae51-3d12a0b69657 Author role: user Content parts: ['Pythonプログラミングを学習する手順を200文字以内で教えてください。'] Model_slug: gpt-4 Message ID: 8be7ff68-cb33-4c35-99c4-a7cd91709886 Author role: assistant Content parts: ['1. Python基礎を学ぶ: 公式ドキュメントやオンラインチュートリアルを利用\n2. 実践的なプロジェクトに取り組む: 小さなタスクを解決するコードを書く\n3. エラーに対処: スタックオーバーフロー等で情報収集し、デバッグスキルを身につける\n4. コード品質向上: PEP 8のルールに従い、リーダブルでメンテナブルなコードを書く\n5. Pythonライブラリを使う: Numpy、Pandas、Matplotlib等の一般的なライブラリを習得\n6. プログラミングコミュニティに参加: 知識共有やフィードバックを得るために活動'] Title: Python Learning Steps. Create time: 1681601151.659016 Update time: 1681601157.0 Current node: 527c93ba-febe-4bd3-9783-f17f8835da14 Message ID: 8f6da518-2767-426c-bd56-a8e7cae1c8b3 Author role: system Content parts: [''] Message ID: 335bf015-2d56-4dbf-9148-eb6be0834b18 Author role: user Content parts: ['Pythonプログラミングを学習する手順を200文字以内で教えてください。'] Model_slug: text-davinci-002-render-sha Message ID: 527c93ba-febe-4bd3-9783-f17f8835da14 Author role: assistant Content parts: ['Pythonプログラミングを学習する手順は以下の通りです。\n\n1. Pythonの基本概念を学ぶ:データ型、演算子、制御構造、関数などの基本的な要素を学びます。\n\n2. Pythonの統合開発環境(IDE)をインストールする:例えば、Anaconda、PyCharmなどのIDEをインストールし、使い方を覚えます。\n\n3. プログラミングの実践:学習したことを活かし、小さなプログラムを書いて実践します。例えば、簡単な計算機や文字列処理などを書いてみます。\n\n4. ライブラリを学ぶ:Pythonの強力なライブラリを活用することで、効率的なプログラムを作成することができます。例えば、NumPy、Pandas、Matplotlibなどのライブラリを学びます。\n\n5. 実践プロジェクトを行う:学習したことを活かし、実践的なプロジェクトを行い、問題を解決することができるようになります。例えば、Webスクレイピング、データ分析、機械学習などのプロジェクトを行います。\n\n6. コミュニティに参加する:Pythonの学習者コミュニティに参加することで、他の人と情報を共有し、相互に学び合うことができます。例えば、Stack Overflow、GitHub、Pythonユーザー会などに参加します。'] (base) kasama.yoshikitmp %
message_feedback.json
message_feedback.json
は、ChatGPTに対するユーザーからのフィードバックを格納するjsonファイルです。このファイルにはユーザーが提供したフィードバックや評価がjson形式で保存されます。会話毎に構造化されており、rating
で先ほどgoodボタンを押したので、thumbsUp
(いいね)となっており、contents
のtextにユーザーのコメントが格納されています。
[ { "message_id": "527c93ba-febe-4bd3-9783-f17f8835da14", "conversation_id": "78fd8d35e0a643bbac9b5702879712a1", "user_id": "<user-id>", "rating": "thumbsUp", "content": "{\"text\": \"\\u3068\\u3066\\u3082\\u53c2\\u8003\\u306b\\u306a\\u308a\\u307e\\u3057\\u305f\\u3002\\u3042\\u308a\\u304c\\u3068\\u3046\\u3054\\u3056\\u3044\\u307e\\u3059\\u3002\"}" }, { "message_id": "8be7ff68-cb33-4c35-99c4-a7cd91709886", "conversation_id": "b84bf73cd71e4ed4b7e4a245107c61fc", "user_id": "<user-id>", "rating": "thumbsUp", "content": "{\"text\": \"\\u3068\\u3066\\u3082\\u53c2\\u8003\\u306b\\u306a\\u308a\\u307e\\u3057\\u305f\\u3002\\u3042\\u308a\\u304c\\u3068\\u3046\\u3054\\u3056\\u3044\\u307e\\u3059\\u3002\"}" } ]
model_comparisons.json
こちらについては4/16現段階では、使用方法がわかっていないため、空で出力されています。
[]
ChatGPTに質問した回答を載せておきますが、正確な情報ではないため、参考までにお願いします。
user.json
user.json
は、ChatGPTに登録されているユーザーアカウント情報を格納するjsonファイルです。基本的な情報からchatgpt plusユーザーかどうかのフラグも保持しているようです。
{ "id": "<user-id>", "email": "<email-address>", "chatgpt_plus_user": true, "phone_number": "<phone-number>" }
おまけ
Clear conversation
すると以前の履歴データはExportできなくなるので、注意が必要です。
あくまで、左のタブに表示されているスレッドのみをExportできます。
最後に
model_comparisons.json
やconversations.json
については、もう少し調査をしてどのような構造かを紐解きたいと思いました。公式documentについても最新情報を随時watchしていきたいと思います。